package com.vanke.devops.api.base;

import com.baomidou.mybatisplus.plugins.Page;
import com.vanke.core.bean.ApiBaseResponse;
import com.vanke.core.bean.PagingResponse;
import com.vanke.core.exception.VankeBusinessException;
import com.vanke.core.exception.VankeCommonExCodeEnum;
import com.vanke.devops.dal.base.BaseModel;
import com.vanke.devops.domain.base.IBaseService;
import com.vanke.devops.domain.domain.users.dto.UsersDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Youzhijie
 * @since 2017-12-05
 */
public abstract class AbstractController<T extends IBaseService> extends BaseController {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    protected T service;

    public PagingResponse queryWithPage(Map<String, Object> param) throws VankeBusinessException {
        Map<String, Object> camelCaseMap = new HashMap<String, Object>();
        covertUnderscopeMapToCamelCaseMap(param, camelCaseMap);
        Page<?> list = service.queryPage(camelCaseMap);
        PagingResponse response = (PagingResponse) setResponse(list);
        return response;
    }

    public PagingResponse queryWithPage(BaseModel param, Integer pageSize, Integer pageNo) throws VankeBusinessException {
        Page<?> list = service.queryPageByFieldsOrKeyword(pageNo,pageSize,param);
        PagingResponse response = (PagingResponse) setResponse(list);
        return response;
    }

    public ApiBaseResponse queryList(Map<String, Object> param) throws VankeBusinessException {
        Map<String, Object> camelCaseMap = new HashMap<String, Object>();
        covertUnderscopeMapToCamelCaseMap(param, camelCaseMap);
        List<?> list = service.queryList(camelCaseMap);
        return setResponse(list);
    }

    public ApiBaseResponse queryList(BaseModel param) throws VankeBusinessException {
        List<?> list = service.queryListByFieldsOrKeyword(param);
        return setResponse(list);
    }

    public ApiBaseResponse getDetail(BaseModel param) throws VankeBusinessException {
        if (param.getId() == null) {
            throw new VankeBusinessException(VankeCommonExCodeEnum.INVALID_REQUEST_FORMAT);
        }
        BaseModel result = (BaseModel) service.queryById(param.getId());
        return setResponse(result);
    }

    public ApiBaseResponse getDetail(Integer id) throws VankeBusinessException {
        BaseModel result = (BaseModel) service.queryById(id);
        return setResponse(result);
    }

    public ApiBaseResponse updateRecord(BaseModel param) throws VankeBusinessException {
        service.update(param);
        return setResponse();
    }

    public ApiBaseResponse updateRecord(Integer id, BaseModel param) throws VankeBusinessException {
        param.setId(id);
        service.update(param);
        return setResponse();
    }

    public ApiBaseResponse addRecord(BaseModel param) throws VankeBusinessException {
        service.add(param);
        return setResponse(param.getId());
    }

    public ApiBaseResponse deleteRecord(BaseModel param) throws VankeBusinessException {
        if (param.getId() == null) {
            throw new VankeBusinessException(VankeCommonExCodeEnum.INVALID_REQUEST_FORMAT);
        }
        service.logicDel(param.getId());
        return setResponse();
    }

    public ApiBaseResponse deleteRecord(Integer id) throws VankeBusinessException {
        service.logicDel(id);
        return setResponse();
    }

    public void covertUnderscopeMapToCamelCaseMap(Map<String, Object> underscopeMap, Map<String, Object> camelCaseMap){
        if(underscopeMap == null){
            return;
        }
        for(Map.Entry<String, Object> entry : underscopeMap.entrySet()){
            camelCaseMap.put(toCamelCase(entry.getKey()), entry.getValue());
        }
    }

    public String toCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '_') {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

